import re
import copy
from enetity_extraction.json_result import generate_return_json
# def process_dict(d):
#     for key, value in d.items():
#         if isinstance(value, dict):
#             process_dict(value)
#         elif isinstance(value, list):
#             for item in value:
#                 if isinstance(item, dict):
#                     process_dict(item)
#         elif isinstance(value, str):
#             d[key] = '0' if value == '' else '1'

desc_dict = {
    '当事人（自然人）信息缺失': '当事人是自然人的，应当写明其姓名、性别、出生年月日、民族、职业或者工作单位和职务、住所。职业或者工作单位和职务不明确的可以不表述应结合身份证信息进行监测（男、女）。',
    '当事人（法人）信息缺失': '1、当事人是法人的，写明名称和住所，并另起一行写明法定代表人的姓名和职务。\n2、当事人是其他组织的，写明名称和住所，并另起一行写明负责人的姓名和职务。\n3、当事人是个体工商户的，写明经营者的姓名、性别、出生年月日、民族、住所；起有字号的，以营业执照上登记的字号为当事人，并写明该字号经营者的基本信息。\n4、当事人是起字号的个人合伙的，在其姓名之后用括号注明“系……（写明字号）合伙人”。',
    '法定代表人信息缺失': '有法定代理人或指定代理人的，应当在当事人之后另起一行写明其姓名、性别、职业或工作单位和职务、住所',
    '委托诉讼代理人信息缺失': '当事人有委托诉讼代理人的，应当在当事人之后另起一行写明为“委托诉讼代理人”，并写明委托诉讼代理人的姓名和其他基本情况。有两个委托诉讼代理人的，分行分别写明。'
}


def check_sequence(s, chars):
    """判断chars中的字符是否按顺序出现在s中"""
    chars_num = len(chars)
    pattern = ''
    for i in range(chars_num):
        pattern += f'.*{chars[i]}'
    pattern = pattern.replace('.*', '', 1)
    return re.search(pattern, s) is not None

def split_chinese_string(s):
    """将字符串按标点符号切分，并且去除切分后的元素中的空格符"""
    # 定义中文标点符号的正则表达式
    punctuation_pattern = r'[,.!?/\#@$%^&*()-=+，。、；：？！“”‘’『』「」【】《》（）\[\]{}<>]'
    # 使用re.split进行分割，同时保留分割后的元素
    parts = re.split(punctuation_pattern, s)
    # 过滤掉空字符串，去除标点符号
    # result = [part.replace(' ', '') for part in parts if part.strip()]
    result = [part.split('\u3000') for part in parts]
    return result



def replace_provinces_with_empty(sentence):
    """替换句子中的省份"""
    # 定义中国省份全称列表
    provinces = [
        "北京市", "天津市", "上海市", "重庆市",
        "河北省", "山西省", "辽宁省", "吉林省", "黑龙江省",
        "江苏省", "浙江省", "安徽省", "福建省", "江西省", "山东省",
        "河南省", "湖北省", "湖南省", "广东省", "海南省",
        "四川省", "贵州省", "云南省", "陕西省", "甘肃省",
        "青海省", "台湾省",
        "北京", "天津", "上海", "重庆",
        "河北", "山西", "辽宁", "吉林", "黑龙江",
        "江苏", "浙江", "安徽", "福建", "江西", "山东",
        "河南", "湖北", "湖南", "广东", "海南",
        "四川", "贵州", "云南", "陕西", "甘肃",
        "青海", "台湾",
        "内蒙古自治区", "广西壮族自治区", "西藏自治区", "宁夏回族自治区", "新疆维吾尔自治区"
    ]

    # 替换句子中的省份名称为空字符串
    for province in provinces:
        sentence = sentence.replace(province, "")

    return sentence



def check_person(plaintiff, desc=''):
    """
    这里检查的是原告、被告、上述人、被上述人、第三人的信息
    :param plaintiff:
    :param desc: 描述的是现在在处理的是什么身份 desc的候选集只有 原告、被告、第三人、上诉人、被上述人
    :return:
    """
    assert desc in ['原告', '被告', '第三人', '上诉人', '被上诉人'], 'desc的描述在候选集之外'
    natural_person_ignore_list = ['户籍地', '身份证号', '职业或工作单位或职务']  # 自然人不需要判断的信息
    name_list = []  # 存储非落款信息中的名字
    output_dict_list = []

    for pidx in range(len(plaintiff)):
        if len(plaintiff[pidx]['all_info']) == 0: continue
        role_tmp = []
        # 自然人
        if '公司名称' not in plaintiff[pidx].keys():
            for k, v in plaintiff[pidx].items():
                if k == '角色':
                    continue
                if k in natural_person_ignore_list: continue
                if k == '姓名':
                    if len(v) != 0:
                        name_list.append(v['match'])
                        if len(v['match']) == 1:
                            role_tmp.append(f'有【{desc}】（自然人）的【姓名】信息“{v["match"]}“不缺失但是不完整！')
                    else:
                        role_tmp.append(f'有【{desc}】（自然人）的【姓名】信息缺失！')
                if len(v) == 0 and k != '姓名':
                    if len(plaintiff[pidx]["姓名"]) != 0: # 说明姓名有内容
                        role_tmp.append(f'【{desc}】（自然人）:{plaintiff[pidx]["姓名"]["match"]}的【{k}】缺失！')
                    else:
                        role_tmp.append(f'有【{desc}】（自然人）:既缺失姓名又缺失【{k}】！')

            if len(role_tmp) != 0:
                role_desc = ''
                for i in range(len(role_tmp)): role_desc += f'{i+1}. {role_tmp[i]}\n'
                role_desc += desc_dict['当事人（自然人）信息缺失']
                output_dict_list.append(generate_return_json(
                    type=f'{desc}信息缺失',
                    explain=role_desc,
                    start=plaintiff[pidx]['all_info']['start_pos'],
                    end=plaintiff[pidx]['all_info']['end_pos']
                ))
        else:
            representative_per = False # 是否有代表人信息缺失 若缺失为True
            if '代表人' not in plaintiff[pidx].keys():
                output_dict_list.append(generate_return_json(
                    type=f'代表人信息缺失',
                    explain=f'代表人不能为空，必须有法定代表人。',
                    start=plaintiff[pidx]['all_info']['start_pos'],
                    end=plaintiff[pidx]['all_info']['end_pos']
                ))
            for k, v in plaintiff[pidx].items():
                if k == '角色':
                    continue
                if k == '代表人':
                    for k2, v2 in v.items():
                        if k2 in natural_person_ignore_list: continue
                        if k2 == '姓名':
                            if len(v2) != 0:
                                name_list.append(v2['match'])
                                if len(v2['match'])==1:
                                    role_tmp.append(f'有【{desc}】（公司/机构）的代表人的【姓名】信息“{v2["match"]}“不缺失但是不完整！')
                            else:
                                role_tmp.append(f'有【{desc}】（公司/机构）的代表人的【姓名】信息缺失！')
                                representative_per = True
                        if len(v2) == 0:
                            representative_per = True
                            if len(plaintiff[pidx][k]['姓名']) != 0:
                                role_tmp.append(f'【{desc}】（公司/机构）的代表人:{plaintiff[pidx][k]["姓名"]["match"]}的【{k2}】缺失！')
                            else:
                                role_tmp.append(f'有【{desc}】（公司/机构）的代表人既缺失姓名又缺失【{k2}】！')
                    continue
                if len(v) == 0:
                    if len(plaintiff[pidx]["公司名称"]) != 0:
                        role_tmp.append(f'【{desc}】（公司/机构）:{plaintiff[pidx]["公司名称"]["match"]}的【{k}】缺失！')
                    else:
                        role_tmp.append(f'有【{desc}】（公司/机构）的【{k}】信息缺失！')

            if len(role_tmp) != 0:
                role_desc = ''
                for i in range(len(role_tmp)): role_desc += f'{i+1}. {role_tmp[i]}\n'
                role_desc += desc_dict['当事人（法人）信息缺失']
                if representative_per: role_desc += f'\n{desc_dict["法定代表人信息缺失"]}\n'
                output_dict_list.append(generate_return_json(
                    type=f'{desc}信息缺失',
                    explain=role_desc,
                    start=plaintiff[pidx]['all_info']['start_pos'],
                    end=plaintiff[pidx]['all_info']['end_pos']
                ))
    return output_dict_list, name_list

def llt_rule_check(cases_section):
    """
    判断当事人、企业、代理人、律师、信息是否缺失
    审判长是否只有一个或是重复
    非审批人员是否在落款中
    :param cases_section:
    :return:
    """
    natural_person_ignore_list = ['户籍地', '身份证号', '职业或工作单位或职务'] # 自然人不需要判断的信息

    plaintiff = cases_section['原告信息']
    defendant = cases_section['被告信息']
    agent = cases_section['委托诉讼代理人信息'] # 律师或者代理人信息
    luo_kuan = cases_section['尾部落款信息']
    third_party = cases_section['第三人']
    shangshu = cases_section['上诉人']
    shangshu_after = cases_section['被上诉人']

    # out_list = [] # 输出信息
    name_list = [] # 存储非落款信息中的名字

    output_dict_list = []

    # 原告信息判断
    output_dict_list_sub, name_list_sub = check_person(plaintiff, '原告')
    name_list += name_list_sub
    output_dict_list += output_dict_list_sub
    # 被告信息判断
    output_dict_list_sub, name_list_sub = check_person(defendant, '被告')
    name_list += name_list_sub
    output_dict_list += output_dict_list_sub
    # 第三人信息
    output_dict_list_sub, name_list_sub = check_person(third_party, '第三人')
    name_list += name_list_sub
    output_dict_list += output_dict_list_sub
    # 上述人
    output_dict_list_sub, name_list_sub = check_person(shangshu, '上诉人')
    name_list += name_list_sub
    output_dict_list += output_dict_list_sub
    # 被上述人
    output_dict_list_sub, name_list_sub = check_person(shangshu_after, '被上诉人')
    name_list += name_list_sub
    output_dict_list += output_dict_list_sub


    # 委托诉讼代理人
    for aidx in range(len(agent)):
        if len(agent[aidx]['all_info']) == 0: continue
        role_tmp = []
        if '律师事务所名称' in agent[aidx].keys():
            id_agent = '律师'
        else: id_agent = '非律师'
        for k, v in agent[aidx].items():
            if k == '所属标签':
                continue
            if k == '姓名':
                if len(v) != 0:
                    name_list.append(v['match'])
                    if len(v['match']) == 1:
                        role_tmp.append(f'有【委托诉讼代理人】的【姓名】信息“{v["match"]}”不缺失但是不完整！')
                else:
                    role_tmp.append(f'有【委托诉讼代理人】的【姓名】信息缺失！')
            if len(v) == 0 and k!='姓名':
                if len(agent[aidx]["姓名"]) != 0:
                    role_tmp.append(f'【委托诉讼代理人】（{id_agent}）:{agent[aidx]["姓名"]["match"]}的【{k}】缺失！')
                else:
                    role_tmp.append(f'有【委托诉讼代理人】（{id_agent}）的【姓名】信息缺失！')
            else:
                if k == '法律服务所的名称及执业身份' :
                    a = v['match']
                    a = a.replace('律师事务所律师', '')
                    # a = a.replace('律师事务所', '')
                    if len(a) == 0:
                        role_tmp.append(f'有【委托诉讼代理人】（{id_agent}）的【律师事务所名称】信息不缺失但不完整！')
                    else:
                        a = replace_provinces_with_empty(a)
                        if len(a) == 0:
                            role_tmp.append(f'有【委托诉讼代理人】（{id_agent}）的【律师事务所名称】信息不缺失但不完整！')

        if len(role_tmp) != 0:
            role_desc = ''
            for i in range(len(role_tmp)): role_desc += f'{i + 1}. {role_tmp[i]}\n'
            role_desc += desc_dict['委托诉讼代理人信息缺失']
            output_dict_list.append(generate_return_json(
                type=f'委托诉讼代理人信息缺失',
                explain=role_desc,
                start=agent[aidx]['all_info']['start_pos'],
                end=agent[aidx]['all_info']['end_pos']
            ))

    # 尾部落款信息中 审判长是否重复 或是只有一个 ； 非审判人员是否在落款中
    # 陪审员、书记员、审批员、审判长、法官助理
    presiding_judge = [] # 审判长
    judge = []  # 审判员  代理审判员 人民陪审员 中出现过的名字

    # 待定
    # juror = [] # 陪审员
    # clerk = [] # 书记员
    # assistant = [] # 法官助理
    # judge = [] # 审判员


    min_paragraph_idx = 999999 # 判断审判长出现时候 是否是第一个
    presiding_judge_idx = -1 # 记录审判长的段落
    judge_name_list = ['审判员', '代理审判员', '人民陪审员'] # 除了法官以外的审判人员列表
    all_judge_name_list = ['审判长', '审判员', '代理审判员', '人民陪审员']
    all_luokuan_name_list = ['审判长', '审判员', '代理审判员', '人民陪审员', '书记员'] # 可以出现在落款中的身份
    if len(luo_kuan) == 0:
        output_dict_list.append(generate_return_json(
            type=f'落款信息为空',
            explain=f'未写任何落款信息'
        ))
    else:
        for l in luo_kuan:
            if l['paragraph_index'] < min_paragraph_idx:
                min_paragraph_idx = l['paragraph_index']
            for name in all_luokuan_name_list:
                if check_sequence(l['match'], name) == True:
                    l_sub_idx = l['match'].find(name[-1])
                    l_sub = l['match'][:l_sub_idx+1]
                    break

            l_sub = l_sub.replace(' ', '').strip() # l_sub 表示职位 这里假设键值对是写了的 而没有出现没有写身份职位的情况
            if l_sub not in all_luokuan_name_list and not (set(['年', '月', '日']) & set(l['match'])):
                output_dict_list.append(generate_return_json(
                    type=f'非审判人员在落款中',
                    start=l['start_pos'],
                    end=l['end_pos'],
                    explain=f'非审判人员身份出现在了落款中：【{l["match"]}】'
                ))

            if check_sequence(l['match'], '审判长') == True:
                presiding_judge_idx = l['paragraph_index']
                a = l['match'].replace('审', '').replace('判', '').replace('长', '').strip()

                # 判断是否有 title后面为空的情况
                if len(a)==0:
                    output_dict_list.append(generate_return_json(
                        type=f'审判长姓名为空',
                        start=l['start_pos'],
                        end=l['end_pos'],
                        explain=f'审判长后没有写明 审判长姓名'
                    ))
                a = a.replace(' ', '\u3000') # 这里做一个鲁棒 担心前面的人将落款信息中的不间断空格打成普通空格
                name_spzs = split_chinese_string(a)
                # 记录出现过的审判长名字
                for name_spz in name_spzs:
                    is_single_name = True
                    for n in name_spz:
                        if len(n) != 1: # 没全拆分成为单个字的情况 说明出现了多个名字
                            presiding_judge.append(n)
                            is_single_name = False
                    if is_single_name:
                        presiding_judge.append(''.join(name_spz))
            # 判断除了审判长以外的审判员
            for jn in judge_name_list:
                if check_sequence(l['match'], jn) == True:
                    jn_list = [char for char in jn]
                    a = l['match']
                    for jn_item in jn_list:
                        a = a.replace(jn_item, '')
                    a = a.strip()

                    # 判断是否有 title后面为空的情况
                    if len(a) == 0:
                        output_dict_list.append(generate_return_json(
                            type=f'审判员姓名为空',
                            start=l['start_pos'],
                            end=l['end_pos'],
                            explain=f'{jn}后没有写明 审判员姓名'
                        ))
                    a = a.replace(' ', '\u3000')  # 这里做一个鲁棒 担心前面的人将落款信息中的不间断空格打成普通空格
                    name_spzs = split_chinese_string(a)
                    # 记录出现过的审判长名字
                    for name_spz in name_spzs:
                        is_single_name = True
                        for n in name_spz:
                            if len(n) != 1:  # 没全拆分成为单个字的情况 说明出现了多个名字
                                judge.append(n)
                                is_single_name = False
                        if is_single_name:
                            judge.append(''.join(name_spz))

            b = l['match'].replace('　', '').strip()
            for name in name_list:
                if b.find(name) != -1:
                    # out_list.append(f'前文提到的姓名：{name} 出现在了落款中')
                    output_dict_list.append(generate_return_json(
                        type=f'非审判人员在落款中',
                        start=l['start_pos'],
                        end=l['end_pos'],
                        explain=f'前文提到的姓名：{name} 出现在了落款中'
                    ))
        if len(set(presiding_judge)) < len(presiding_judge):
            # out_list.append(f'审判长重复，{"、".join(presiding_judge)}')
            output_dict_list.append(generate_return_json(
                type='审判长重复',
                explain=f'审判长重复，{"、".join(presiding_judge)}'
            ))
        if len(set(presiding_judge)) >=2:
            # out_list.append(f'出现不止一个审判长，{"、".join(presiding_judge)}')
            output_dict_list.append(generate_return_json(
                type=f'出现不止一个审判长',
                explain=f'出现不止一个审判长，{"、".join(presiding_judge)}'
            ))

        if set(presiding_judge) & set(judge):
            output_dict_list.append(generate_return_json(
                type=f'审判长和审判员重复',
                explain=f'审判长和审判员出现重复，审判长有【{" ".join(presiding_judge)}】，审判员有【{" ".join(judge)}】'
            ))

        if len(set(judge)) < len(judge):
            output_dict_list.append(generate_return_json(
                type='审判员重复',
                explain=f'审判员重复，{"、".join(judge)}'
            ))
        num_judge = len(judge) + len(presiding_judge) # 所有审判人员的数量
        if num_judge!=0:
            if num_judge%2 != 1:
                if len(presiding_judge) != 0 and len(judge) != 0:
                    explain_out = f'审判人员不能为双数，这里出现了{num_judge}个，分别是审判长【{" ".join(presiding_judge)}】和审判员【{" ".join(judge)}】'
                elif len(presiding_judge) == 0:
                    explain_out = f'审判人员不能为双数，这里出现了{num_judge}个，分别是审判员【{" ".join(judge)}】'
                else:
                    explain_out = f'审判人员不能为双数，这里出现了{num_judge}个，分别是审判长【{" ".join(presiding_judge)}】'
                output_dict_list.append(generate_return_json(
                    type='审判人员不能为双数',
                    explain=explain_out
                ))
        else:
            output_dict_list.append(generate_return_json(
                type='审判人员不能为空',
                explain=f'审判人员不能为空，这里没有出现任何审判人员'
            ))

        # 判断审判长是否是第一个
        if min_paragraph_idx != presiding_judge_idx and len(set(presiding_judge)) < 2:
            output_dict_list.append(generate_return_json(
                type=f'审判长在落款中必须是第一个',
                explain=f'若出现审判长，审判长应写在落款中的第一个'
            ))


    return output_dict_list

if __name__ == '__main__':
    from enetity_extraction.test_docx import get_docx_extraction_result
    # from enetity_extraction.test_docx import get_docx_extraction_result
    from enetity_extraction.company_data_test import get_data

    test_data = get_data()


    # for i in range(24, 47):
    #     # if i != 36: continue
    #     sentence_extract = extract_information([test_data[i]['错误用例']])
    #     output_dict_list = information_judgment2(sentence_extract)
    #     print(f'第{i+1}个测试用例')
    #     for o in output_dict_list:
    #         print(o['type'])
    #     print('*'*60)

    _, result = get_docx_extraction_result('../enetity_extraction/0815改错不报文书/test.docx')
    # result = get_docx_extraction_result('../enetity_extraction/0725_test_data/7-邱志娥与吴胜熙民间借贷纠纷一审民事案133690201.docx')
    output_dict_list = llt_rule_check(result)
    for o in output_dict_list:
        print(f'type: {o["type"]}')
        print(f'explain:\n{o["explain"]}')
        print(f'start:{o["start"]}')
        print(f'end:  {o["end"]}')
        print('*' * 60)

    # a = '黔西南布依族苗族自治州中级人民法院\n民事案（20178）黔23民初47号\n原告：组织机构代码：31422731-2'
    # a = a.split('\n')
    # sentence_extract = extract_information(a)
    # output_dict_list = information_judgment2(sentence_extract)
    # for o in output_dict_list:
    #     print(o['type'])
    # print('*' * 60)